<?php
declare (strict_types=1);

namespace app\model\home;

use app\common\model\BaseModel;
use app\common\model\Store;
use app\controller\home\TxSms;
use app\model\admin\Member;
use \libs\Log;
use think\App;
use think\Exception;
use function GuzzleHttp\Psr7\str;

class Book extends BaseModel
{
    protected $pk = 'id';

    protected function initialize()
    {
        parent::initialize();
    }

    /**
     * @param $value
     * @return false|string|void
     * 开始时间
     */
    protected function getStartAtAttr($value)
    {
        if ($value) {
            return date('Y-m-d H:i:s', $value);
        }
    }

    /**
     * @param $value
     * @return false|string|void
     * 开始时间
     */
    protected function getStartStrAttr($value)
    {
        if ($value) {
            return date('Y-m-d H:i', $value);
        }
    }

    /**
     * @param $value
     * @return false|string|void
     * 开始时间
     */
    protected function getEndStrAttr($value)
    {
        if ($value) {
            return date('H:i', $value);
        }
    }

    /**
     * @param $value
     * @return false|string|void
     * 结束时间
     */
    protected function getEndAtAttr($value)
    {
        if ($value) {
            return date('Y-m-d H:i:s', $value);
        }
    }

    /**
     * @param $value
     * @return mixed|string
     * 获取用户昵称
     */
    protected function getMemberNameAttr($value)
    {
        return Member::where('member_id', $value)->value('nickname') ?: '';
    }

    /**
     * @param $value
     * @return false|int
     * 开始时间修改器
     */
    protected function setStartTimeAttr($value)
    {
        return strtotime($value);
    }

    /**
     * @param $value
     * @return false|int
     * 截止时间修改器
     */
    protected function setEndTimeAttr($value)
    {
        return strtotime($value);
    }

    /**
     * @param $value
     * @return mixed|string
     * 游戏名
     */
    protected function getGameTitleAttr($value)
    {
        return Game::where('id', $value)->value('game_title') ?: '';
    }

    /**
     * @param $value
     * @return mixed|string
     * 门店名称
     */
    protected function getStoreNameAttr($value)
    {
        return Store::where('id', $value)->value('store_name') ?: '';
    }

    /**
     * 获得列表
     * @param bool $where
     * @param string $fields
     * @param string|null $order
     * @param int $page
     * @param int $pageSize
     * @return array
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\DbException
     * @throws \think\db\exception\ModelNotFoundException
     */
    public function getList($where = true, $fields = '*', $order = null, $page = 1, $pageSize = 20)
    {
        $data = [
            'count' => 0,
            'list' => []
        ];
        $count = $this->where($where)->count();
        if (empty($count)) {
            return $this->returnRight($data);
        }
        $order = is_null($order) ? $this->pk . ' desc' : $order;
        $list = $this->where($where)
            ->field($fields)
            ->order($order)
            ->page($page, $pageSize)
            ->select();
        $data['count'] = $count;
        $data['list'] = $list;
        return $this->returnRight($data);
    }

    /**
     * @param $data
     * @return array
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\DbException
     * @throws \think\db\exception\ModelNotFoundException
     * 详情
     */
    public function getOne($data)
    {
        $usedTimeArr = [];
        $where['re_id'] = $data['re_id'];
        $where['status'] = 1;
        //包间
        if ($data['re_type'] == 2) {
            $storeId = Room::where('id', $data['re_id'])->value('store_id');
            $store = \app\model\admin\Store::where('id', $storeId)->field('id,start_time,end_time')->find();
            $usedTimeArr[] = strtotime($data['duty_date'] . ' ' . $store['start_time']);
            $usedTimeArr[] = strtotime($data['duty_date'] . ' ' . $store['end_time']);
        } else {
            $map[] = ['duty_date', '=', $data['duty_date']];
            $map[] = ['re_id', '=', $data['re_id']];
            $map[] = ['status', 'in', [1, 2]];
            $duty = Duty::where($map)->field('duty_date,start_timestr,end_timestr')->select();
            foreach ($duty->toArray() as $v) {
                $usedTimeArr[] = strtotime($v['duty_date'] . ' ' . $v['start_timestr']);
                $usedTimeArr[] = strtotime($v['duty_date'] . ' ' . $v['end_timestr']);
            }
        }
        $usedTimeArr = array_unique($usedTimeArr);
        if (empty($usedTimeArr)) {
            $list = [
                "work_time" => "",
                "time_arr" => []
            ];
            return $this->returnRight($list);
        }
        sort($usedTimeArr);
        //因为早中晚班都是两个时间点所以考虑不是连续时间(早班、晚班没有中班的情况)
        //每两个分一组
        $timeArr = [];
        for ($i = 0; $i <= count($usedTimeArr); $i += 2) {
            if (isset($usedTimeArr[$i + 1])) {
                $timeArr[] = getTimeArr($usedTimeArr[$i + 1], $usedTimeArr[$i]);
            }

        }
        $timeArr = array_unique(array_reduce($timeArr, 'array_merge', []));
        $min = min($timeArr);
        $max = max($timeArr);
        $nowDate = date('Y-m-d', time());
        foreach ($timeArr as $k => $time) {
            $list[$k]['value'] = $time;
            if (!empty($data['duty_date']) && $nowDate > $data['duty_date']) {
                $list[$k]['checked'] = false;
            } else {
                //判断助教当天是否被预约
                $start = date('Y-m-d 00:00:00', strtotime($data['duty_date']));
                $end = date('Y-m-d 23:59:59', strtotime($data['duty_date']));
                $bookCount = $this->where($where)->whereTime('start_time', 'between', [$start, $end])->count();
                //已预约的时间、过期的时间
                if (!empty($bookCount) || strtotime($time) < strtotime(date("Y-m-d 23:59:59", time()))) {
                    $list[$k]['checked'] = false;
                } else {
                    $list[$k]['checked'] = true;
                }
            }
        }
        foreach ($list as $item) {
            $item['value'] = date('H:i', strtotime($item['value']));
            $listArr[] = $item;
        }
        $listRow['work_time'] = date('H:i', strtotime($min)) . '-' . date('H:i', strtotime($max));
        $listRow['time_arr'] = $listArr;
        return $this->returnRight($listRow);
    }

    /**
     * 添加
     * @param array $data
     * @return array
     */
    public function add(array $data)
    {

        $startAt = strtotime($data['start_time']);
//        if ($startAt < time()) {
//            return $this->returnError(28);
//        }
        $endAt = strtotime($data['end_time']);
        $todayTime = strtotime(date('Y-m-d 00:00:00', time()));
//        if ($endAt < $todayTime) {
//            return $this->returnError(28);
//        }
        $where['member_id'] = $data['member_id'];
        $where['re_id'] = $data['re_id'];
        $where['re_type'] = $data['re_type'];
        $where['store_id'] = $data['store_id'];
        $where['status'] = 1;

        $map['re_id'] = $data['re_id'];
        $map['re_type'] = $data['re_type'];
        $map['status'] = 1;
        $count = $this->where($map)->whereTime('start_time', 'today')->count();
        if (!empty($count)) {
            return $this->returnError(38);
        }
        $infoArr = $this->where($where)->field('start_time,end_time')->select()->toArray();
        if (!empty($infoArr)) {
            $usedTimeArr = [];
            if (!empty($infoArr)) {
                foreach ($infoArr as $v) {
                    $usedTimeArr[] = $v['start_time'];
                    $usedTimeArr[] = $v['end_time'];
                }
            }
            $min = min($usedTimeArr);
            $max = max($usedTimeArr);
            if ($startAt >= $min && $endAt <= $max) {
                return $this->returnError(27);
            }
        }
        try {
            $this->startTrans();
            //用户信息
            $nickName = Member::where('member_id', $data['member_id'])->value('nickname');
            $book = self::create($data);
            //预约成功给助教发送短信
            if ($data['re_type'] == 1) {
                $assistantInfo = Assistant::where('id', $data['re_id'])->field('nickname,member_id')->find();
                $phone = Member::where('member_id', $assistantInfo['member_id'])->value('phone');
                TxSms::send($phone, "1324098", [$assistantInfo['nickname'], $nickName]);
            }
            $responseArr = [
                'id' => $book->id
            ];
            $this->commit();
            return $this->returnRight($responseArr);
        } catch (\Exception $ex) {
            $this->rollback();
            return $this->returnException($ex);
        }
    }

    /**
     * @param $data
     * @return array
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\DbException
     * @throws \think\db\exception\ModelNotFoundException
     * 我的预约
     */
    public function myBook($where, $data)
    {
        $this->where($where)->count();
        $myBook = $this->where($where)
            ->field('id,store_id,store_id store_name,member_id member_name,re_id,re_type,game_id game_title,start_time,start_time start_at,end_time,end_time end_at,status')
            ->order('update_time DESC')
            ->select();
        $map['status'] = 1;
        $list = [];
        foreach ($myBook->toArray() as $v) {

            $v['time_range'] = date('Y-m-d H:i', $v['start_time']) . '-' . date('H:i', $v['end_time']);
            $v['now_date'] = date('Y-m-d', $v['start_time']);
            if ($v['start_time'] > time()) {
                $v['time_status'] = 0;
            } else if ($v['end_time'] < time()) {
                $v['time_status'] = 2;
            } else {
                $v['time_status'] = 1;
            }
            $map['id'] = $v['re_id'];
            switch ($v['re_type']) {
                //包间
                case 2:
                    $v['room'] = Room::where($map)
                        ->field('room_cover,per_price,num,start_time,end_time,room_title,room_type')
                        ->find() ?: [];
                    !empty($v['room']) && $v['price'] = $v['room']['per_price'];
                    break;
                default:
                    $v['assistant'] = Assistant::where($map)
                        ->field('nickname,address,per_price,tag,per_price,cover,avatar,hot,score,sign')
                        ->find() ?: [];
                    !empty($v['assistant']) && $v['price'] = $v['assistant']['per_price'];
                    $v['order_no'] = Order::where('book_id', $v['id'])->value('order_no');
            }
            $list[] = $v;
        }
        return $this->returnRight($list);
    }

    /**
     * @param $data
     * @return array
     * 同意预约
     */
    public function approveBook($data)
    {
        //查询
        $assistant_id = Assistant::where('member_id', $data['member_id'])->value('id');
        $book_info = $this->where('id', $data['id'])->field('member_id,re_id,store_id,re_type')->find();
        if ($book_info['re_id'] != $assistant_id) {
            return $this->returnError(37);
        }
        try {
            $this->startTrans();
            //更新状态
            self::update(['status' => 2], ['id' => $data['id']]);
            //给用户发送短信
            $memberInfo = Member::where('member_id', $book_info['member_id'])->field('phone,nickname')->find();
            TxSms::send($memberInfo['phone'], "1324102", [$memberInfo['nickname']]);
        } catch (\Exception $ex) {
            return $this->returnException($ex);
        }

    }

    /**
     * @param $data
     * @return array
     * 拒绝预约
     */
    public function rejectBook($data)
    {
        //查询
        $assistant_id = Assistant::where('member_id', $data['member_id'])->value('id');
        $book_info = $this->where('id', $data['id'])->field('member_id,re_id,store_id,re_type')->find();
        if ($book_info['re_id'] != $assistant_id) {
            return $this->returnError(37);
        }
        $res = self::update(['status' => 3], ['id' => $data['id']]);
        if ($res) {
            return $this->returnSucc();
        } else {
            return $this->returnError(-1);
        }
    }
}
